feat:(REQ-2227) 增加单测,修改角色树查询接口增加查询条件
This commit is contained in:
parent
a79b7e4272
commit
af815aa384
@ -5,6 +5,8 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@ -21,4 +23,22 @@ public class TreeRoleReq {
|
||||
* '是否显示'
|
||||
*/
|
||||
private Boolean isDisplay;
|
||||
|
||||
/**
|
||||
* 项目部id(不传或者传-1查询的是标准分组)
|
||||
*/
|
||||
private List<Long> workspaceIds;
|
||||
|
||||
/**
|
||||
* 单位id(不传或者传-1查询的是标准分组)
|
||||
*/
|
||||
private List<Long> ouIds;
|
||||
|
||||
/**
|
||||
* 端,会转成workspaceTypeCode去过滤根节点
|
||||
* NT_OMS_WEB -> 6
|
||||
* NT_CMS_WEB_GENERAL -> 1,2
|
||||
* NT_CMP_APP_GENERAL -> 1,2
|
||||
*/
|
||||
private String terminal;
|
||||
}
|
||||
@ -105,6 +105,22 @@
|
||||
<groupId>cn.axzo.pokonyan</groupId>
|
||||
<artifactId>pokonyan</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>2.0.202</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 内嵌redis server-->
|
||||
<dependency>
|
||||
<groupId>com.github.caryyu</groupId>
|
||||
<artifactId>spring-embedded-redis-server</artifactId>
|
||||
<version>1.1</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@ -44,6 +44,7 @@ import cn.axzo.tyr.server.service.SaasRoleGroupRelationService;
|
||||
import cn.axzo.tyr.server.service.SaasRoleGroupService;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
@ -59,6 +60,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -98,6 +100,16 @@ public class SaasRoleController implements TyrSaasRoleApi {
|
||||
private static final String ROLE_TYPE = "ROLE";
|
||||
private static final String ROLE_GROUP_TYPE = "ROLE_GROUP";
|
||||
|
||||
/**
|
||||
* 没有统一维护的地方
|
||||
*/
|
||||
private static final Map<String, List<String>> TERMINAL_WORKSPACE_CODES = Maps.newHashMap();
|
||||
static {
|
||||
TERMINAL_WORKSPACE_CODES.put("NT_OMS_WEB", Lists.newArrayList("6"));
|
||||
TERMINAL_WORKSPACE_CODES.put("NT_CMS_WEB_GENERAL", Lists.newArrayList("1", "2"));
|
||||
TERMINAL_WORKSPACE_CODES.put("NT_CMP_APP_GENERAL", Lists.newArrayList("1", "2"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResult<Long> saveOrUpdate(SaveOrUpdateRoleVO saveOrUpdateRole) {
|
||||
Long result = roleService.saveOrUpdate(saveOrUpdateRole);
|
||||
@ -334,6 +346,8 @@ public class SaasRoleController implements TyrSaasRoleApi {
|
||||
.roleIds(Lists.transform(saasRoleGroupRelations, SaasRoleGroupRelation::getRoleId))
|
||||
.isDisplay(req.getIsDisplay())
|
||||
.workspaceType(req.getWorkspaceType())
|
||||
.workspaceIds(req.getWorkspaceIds())
|
||||
.ouIds(req.getOuIds())
|
||||
.build())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(SaasRoleRes::getId, Function.identity()));
|
||||
@ -358,11 +372,13 @@ public class SaasRoleController implements TyrSaasRoleApi {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<SaasRoleGroupVO> roleGroups = saasRoleGroupService.getList(QuerySaasRoleGroupReq.builder()
|
||||
List<SaasRoleGroupVO> roleGroups = saasRoleGroupService.getRoleGroupList(QuerySaasRoleGroupReq.builder()
|
||||
.workspaceTypeCode(Lists.transform(commonDicts, CommonDictResp::getDictCode))
|
||||
.workspaceIds(req.getWorkspaceIds())
|
||||
.ouIds(req.getOuIds())
|
||||
.build())
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(SaasRoleGroupVO::getSort))
|
||||
.sorted(Comparator.comparing(e -> Optional.ofNullable(e.getSort()).orElse(1)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Long, List<RoleTreeRes>> roles = listRole(roleGroups, req);
|
||||
@ -425,9 +441,18 @@ public class SaasRoleController implements TyrSaasRoleApi {
|
||||
}
|
||||
|
||||
private List<CommonDictResp> listRootRole(TreeRoleReq req) {
|
||||
return saasCommonDictService.query(CommonDictQueryReq.builder()
|
||||
CommonDictQueryReq commonDictQueryReq = CommonDictQueryReq.builder()
|
||||
.codes(StringUtils.isBlank(req.getWorkspaceTypeCode()) ? null : Lists.newArrayList(req.getWorkspaceTypeCode()))
|
||||
.scope("role")
|
||||
.build());
|
||||
.build();
|
||||
if (StringUtils.isNotBlank(req.getTerminal())) {
|
||||
List<String> workspaceTypeCodes = TERMINAL_WORKSPACE_CODES.get(req.getTerminal());
|
||||
if (CollectionUtils.isEmpty(workspaceTypeCodes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
commonDictQueryReq.setCodes(workspaceTypeCodes);
|
||||
}
|
||||
|
||||
return saasCommonDictService.query(commonDictQueryReq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,6 +144,12 @@ public interface RoleService extends IService<SaasRole> {
|
||||
@CriteriaField(field = "roleCode", operator = Operator.EQ)
|
||||
private String roleCode;
|
||||
|
||||
@CriteriaField(field = "workspaceId", operator = Operator.EQ)
|
||||
private List<Long> workspaceIds;
|
||||
|
||||
@CriteriaField(field = "ownerOuId", operator = Operator.EQ)
|
||||
private List<Long> ouIds;
|
||||
|
||||
@CriteriaField(ignore = true)
|
||||
private Boolean needPermission;
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ spring:
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
server-addr: ${NACOS_HOST:test-nacos.axzo.cn}:${NACOS_PORT:80}
|
||||
server-addr: ${NACOS_HOST:https://test-nacos.axzo.cn}:${NACOS_PORT:443}
|
||||
file-extension: yaml
|
||||
namespace: ${NACOS_NAMESPACE_ID:f3c0f0d2-bac4-4498-bee7-9c3636b3afdf}
|
||||
---
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<!-- 导入安心筑全局日志配置 -->
|
||||
<include resource="logback/logback-axzo.xml" />
|
||||
<!-- 覆盖开发环境日志配置 -->
|
||||
<springProfile name="local,dev">
|
||||
<springProfile name="local,dev,test">
|
||||
<logger name="cn.axzo" level="DEBUG" />
|
||||
</springProfile>
|
||||
</configuration>
|
||||
@ -0,0 +1,101 @@
|
||||
package cn.axzo.tyr.server.permission;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.io.Files;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.util.AopTestUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(classes = {TestConfig.class})
|
||||
@AutoConfigureMockMvc
|
||||
@Transactional
|
||||
@ActiveProfiles("unittest")
|
||||
public abstract class BaseTest {
|
||||
private static final String JSON_FILE_CLASSPATH = "classpath:json/";
|
||||
|
||||
/**
|
||||
* 记录对象原始的 field 值. 因为这些值可能被mock替换, 在每次执行单元测试前统一进行一次替换恢复
|
||||
* 避免影响后续的单元测试.
|
||||
*/
|
||||
private static Table<Object, String, Object> ORIGIN_FIELD_TABLE = HashBasedTable.create();
|
||||
|
||||
@Autowired
|
||||
protected MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
// restore origin value of field.
|
||||
ORIGIN_FIELD_TABLE.cellSet().stream().forEach(e -> {
|
||||
ReflectionTestUtils.setField(e.getRowKey(), e.getColumnKey(), e.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> T unwrapProxy(Object bean) {
|
||||
return AopTestUtils.getUltimateTargetObject(bean);
|
||||
}
|
||||
|
||||
protected <T> List<T> parseListContent(MvcResult result, Class<T> contentClazz) throws UnsupportedEncodingException {
|
||||
JSONObject response = JSONObject.parseObject(result.getResponse().getContentAsString());
|
||||
return JSON.parseObject(response.getString("content"), new TypeReference<List<T>>(contentClazz) {
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T loadJson(String fileName, Class<T> clz) {
|
||||
try {
|
||||
String jsonString = Files.asCharSource(ResourceUtils.getFile(JSON_FILE_CLASSPATH + fileName), StandardCharsets.UTF_8).read();
|
||||
return JSON.parseObject(jsonString, clz);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("loadJson got error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> loadJsonAsList(String fileName, Class<T> clz) {
|
||||
try {
|
||||
String jsonString = Files.asCharSource(ResourceUtils.getFile(JSON_FILE_CLASSPATH + fileName), StandardCharsets.UTF_8).read();
|
||||
return JSONArray.parseArray(jsonString, clz);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("loadJsonAsList got error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置对象field为mock对象. teardown时恢复成原spring代理的对象
|
||||
*/
|
||||
protected void setMockField(Object targetObject, String fieldName, Object value) {
|
||||
// 保存一份默认值
|
||||
Object oldField = ReflectionTestUtils.getField(targetObject, fieldName);
|
||||
ReflectionTestUtils.setField(targetObject, fieldName, value);
|
||||
|
||||
if (!ORIGIN_FIELD_TABLE.contains(targetObject, fieldName) && oldField != null) {
|
||||
ORIGIN_FIELD_TABLE.put(targetObject, fieldName, oldField);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.axzo.tyr.server.permission;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
|
||||
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasFeatureDao;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasFeature;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DemoTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
private SaasFeatureDao saasFeatureDao;
|
||||
|
||||
@Test
|
||||
void ff() {
|
||||
List<SaasFeature> saasFeatures = saasFeatureDao.listByIds(Arrays.asList(206L, 207L, 208L));
|
||||
System.out.println(JSON.toJSONString(saasFeatures));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,132 @@
|
||||
package cn.axzo.tyr.server.permission;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.Files;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* mysql 测试数据加载
|
||||
* <p>
|
||||
* 测试数据后缀.sql, 默认加载 DEFAULT section 的数据. 如果需要加载指定section的数据需要带上sectionName
|
||||
*
|
||||
* <p>
|
||||
* 文件中通过 "#-->"来定义section. loader可以加载指定section的数据.
|
||||
* </p>
|
||||
* <p>
|
||||
* 文件路径: test/resources/mysql/${testClassName}.sql.
|
||||
* <p>
|
||||
* 数据格式如下
|
||||
* <pre>
|
||||
* #-->DEFAULT
|
||||
* sql statement1;
|
||||
* sql statement2;
|
||||
*
|
||||
* #-->section1
|
||||
* sql statement3;
|
||||
* sql statement4;
|
||||
*
|
||||
* #-->section2
|
||||
* sql statement5;
|
||||
* </pre>
|
||||
*
|
||||
* @author chenjun
|
||||
*/
|
||||
@Slf4j
|
||||
public class MysqlDataLoader {
|
||||
|
||||
private final static String MYSQL_DATA_PATH = "classpath:mysql/";
|
||||
private final static String MYSQL_FILE_SUFFIX = ".sql";
|
||||
private final static String DEFAULT_SECTION = "DEFAULT";
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private LoadingCache<File, Multimap<String, String>> sqlFileCaches = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<File, Multimap<String, String>>() {
|
||||
@SuppressWarnings("NullableProblems")
|
||||
public Multimap<String, String> load(File file) throws Exception {
|
||||
List<String> lines = Files.asCharSource(file, Charset.forName("utf-8")).readLines();
|
||||
String sectionFlag = "#-->";
|
||||
Multimap<String, String> sections = LinkedListMultimap.create();
|
||||
String currentSectionName = "";
|
||||
// 按照section分组.
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (StringUtils.isAllBlank(line)) {
|
||||
continue;
|
||||
}
|
||||
String sectionName = StringUtils.substringAfter(line, sectionFlag);
|
||||
if (org.apache.logging.log4j.util.Strings.isNotBlank(sectionName)) {
|
||||
currentSectionName = sectionName;
|
||||
} else {
|
||||
sections.put(currentSectionName, line);
|
||||
}
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
});
|
||||
|
||||
public void loadFromClassName(String className) {
|
||||
String locationPattern = MYSQL_DATA_PATH + className + MYSQL_FILE_SUFFIX;
|
||||
File file = getFile(locationPattern);
|
||||
execStatements(file, ImmutableList.of(DEFAULT_SECTION));
|
||||
}
|
||||
|
||||
|
||||
public void loadFromClassName(String className, List<String> includeSections) {
|
||||
String locationPattern = MYSQL_DATA_PATH + className + MYSQL_FILE_SUFFIX;
|
||||
File file = getFile(locationPattern);
|
||||
execStatements(file, includeSections);
|
||||
}
|
||||
|
||||
public void load(String filePath) {
|
||||
String locationPattern = MYSQL_DATA_PATH + filePath;
|
||||
File file = getFile(locationPattern);
|
||||
execStatements(file, ImmutableList.of(DEFAULT_SECTION));
|
||||
}
|
||||
|
||||
public void load(String filePath, List<String> includeSections) {
|
||||
String locationPattern = MYSQL_DATA_PATH + filePath;
|
||||
File file = getFile(locationPattern);
|
||||
execStatements(file, includeSections);
|
||||
}
|
||||
|
||||
private File getFile(String locationPattern) {
|
||||
File file;
|
||||
try {
|
||||
file = ResourceUtils.getFile(locationPattern);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("try get file error", ex);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private void execStatements(File file, List<String> includeSections) {
|
||||
Multimap<String, String> sections = sqlFileCaches.getUnchecked(file);
|
||||
List<String> statements = sections.entries().stream()
|
||||
.filter(e -> includeSections.isEmpty() || includeSections.contains(e.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.collect(Collectors.toList());
|
||||
String sql = Joiner.on("\n").join(statements);
|
||||
log.info("\n>>>>>>>>>>>>>>> Execute SQL {}\n {}", Joiner.on(",").join(includeSections), sql);
|
||||
jdbcTemplate.update(sql);
|
||||
log.info("<<<<<<<<<<<<< Execute DONE\n");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.axzo.tyr.server.permission;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import redis.embedded.RedisServer;
|
||||
import redis.embedded.exceptions.OsDetectionException;
|
||||
import redis.embedded.util.OS;
|
||||
import redis.embedded.util.OSDetector;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
@Slf4j
|
||||
@TestConfiguration
|
||||
public class TestConfig {
|
||||
|
||||
private RedisServer redisServer;
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() throws IOException {
|
||||
redisServer = new RedisServer(16379);
|
||||
// redis server会在后台启动一个redis server的进程,默认IP=127.0.0.1
|
||||
redisServer.start();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() {
|
||||
// 测试结束后必须调用redisServer.stop(), 否则后台运行的redis server进程会一直存在并占用6379端口
|
||||
redisServer.stop();
|
||||
}
|
||||
}
|
||||
34
tyr-server/src/test/resources/application-unittest.yml
Normal file
34
tyr-server/src/test/resources/application-unittest.yml
Normal file
@ -0,0 +1,34 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:h2:mem:demo;MODE=MySQL;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=0;
|
||||
driver-class-name: org.h2.Driver
|
||||
schema: classpath:/mysql/schema.sql
|
||||
data: classpath:/mysql/data.sql
|
||||
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: 16379
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
xxl:
|
||||
job:
|
||||
admin:
|
||||
# 地址为刚刚配置的调度中心的访问地址
|
||||
addresses: http://xxl-job:8080/xxl-job-admin
|
||||
executor:
|
||||
# 自定义appName(执行器名称)
|
||||
appname: tyr
|
||||
# ip 可以写 (程序跑在的机器ip上),也可以不写
|
||||
ip:
|
||||
port: 9999
|
||||
# 执行器日志文件存储路径
|
||||
# logpath: /data/applogs/xxl-job/jobhandler
|
||||
# 设置日志过期时间 -1表示永不过期
|
||||
logretentiondays: -1
|
||||
accessToken:
|
||||
flush:
|
||||
role1052:
|
||||
saasPreTempalteIdOfProject: 5
|
||||
saasPreTempalteIdOfOu: 43
|
||||
1
tyr-server/src/test/resources/mysql/data.sql
Normal file
1
tyr-server/src/test/resources/mysql/data.sql
Normal file
@ -0,0 +1 @@
|
||||
select 1;
|
||||
56
tyr-server/src/test/resources/mysql/schema.sql
Normal file
56
tyr-server/src/test/resources/mysql/schema.sql
Normal file
@ -0,0 +1,56 @@
|
||||
CREATE TABLE `demo` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(64) NOT NULL COMMENT 'Code, 唯一',
|
||||
`name` VARCHAR(128) NOT NULL COMMENT '名称',
|
||||
-- `tags` JSON NULL COMMENT 'tags, jsonArray',
|
||||
`tags` VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'json tags',
|
||||
`features` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'features功能列表',
|
||||
`description` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '描述',
|
||||
`status` VARCHAR(16) NOT NULL DEFAULT 'ENABLED' COMMENT '状态: ENABLED',
|
||||
-- `ext` JSON NULL COMMENT '额外信息, 使用json便于查询',
|
||||
`ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息',
|
||||
`creator` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '创建人',
|
||||
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`modifier` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '更新人',
|
||||
`modify_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_demo_code` (`code`)
|
||||
) COMMENT ='demo';
|
||||
|
||||
|
||||
CREATE TABLE `saas_feature` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`feature_name` varchar(128) NOT NULL DEFAULT '' COMMENT '名称',
|
||||
`feature_code` varchar(128) NOT NULL DEFAULT '' COMMENT 'code',
|
||||
`icon` varchar(256) NOT NULL DEFAULT '' COMMENT '图标地址',
|
||||
`parent_id` bigint NOT NULL DEFAULT '0' COMMENT '菜单上级id',
|
||||
`parent_module_id` bigint NOT NULL DEFAULT '0' COMMENT '产品板块Id',
|
||||
`link_url` varchar(256) NOT NULL DEFAULT '' COMMENT '链接地址',
|
||||
`link_type` tinyint NOT NULL DEFAULT '1' COMMENT '1:CMS 2:小程序 4:原生',
|
||||
`link_ext` text COMMENT '扩展字段',
|
||||
`micro_app_item_id` varchar(50) NOT NULL DEFAULT '' COMMENT '小程序id 关联micro_app_item id',
|
||||
`path` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '路径',
|
||||
`description` varchar(128) NOT NULL DEFAULT '' COMMENT '描述',
|
||||
`sort` int NOT NULL DEFAULT '5' COMMENT '排序',
|
||||
`terminal` varchar(64) NOT NULL DEFAULT '' COMMENT '菜单适用于平台 0:企业工作台 1:项目工作台 ',
|
||||
`feature_type` tinyint NOT NULL DEFAULT '0' COMMENT '类型 0.模块 1.菜单 2页面 3功能',
|
||||
`is_delete` bigint NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
`create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建人id',
|
||||
`create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`update_by` bigint DEFAULT '0' COMMENT '修改人id',
|
||||
`legacy_layout` varchar(255) NOT NULL DEFAULT '',
|
||||
`operate_type` tinyint DEFAULT NULL COMMENT '0:查看 1:操作',
|
||||
`old_id` bigint DEFAULT NULL COMMENT '为了迁移菜单用的,迁移后将废弃',
|
||||
`fit_ou_type_bit` bigint NOT NULL DEFAULT '65535' COMMENT '适用单位类型-65535:所有 1:总包 2:建设单位 4:监理单位 8:劳务分包 16:专业分包',
|
||||
`fit_ou_node_type_bit` bigint NOT NULL DEFAULT '65535' COMMENT '适用节点类型65535:所有 1:部门 2:班组 4:小组',
|
||||
`app_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '网关专属字段,所属应用',
|
||||
`feature_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '网关专属字段 ,功能URL,对应后端接口url',
|
||||
`need_cert` tinyint(1) NOT NULL DEFAULT '1' COMMENT '网关专属字段,是否认证 0:无需要认证 1:需要认证',
|
||||
`need_auth` tinyint(1) NOT NULL DEFAULT '1' COMMENT '网关专属字段,是否授权 0:无需要授权 1:需要授权',
|
||||
`business_no` varchar(64) DEFAULT NULL COMMENT '业务id,用于环境同步作为唯一键',
|
||||
`parent_business_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '0' COMMENT '父级业务id',
|
||||
`delegated_type` tinyint DEFAULT NULL COMMENT '授权策略类型,允许为空 1-平台授权型 2-客户授权型 3-免授权型',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX_CODE` (`feature_code`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='saas-菜单页面表';
|
||||
Loading…
Reference in New Issue
Block a user