Merge remote-tracking branch 'origin/master' into jsqlparser-fix

This commit is contained in:
zhaoyingchao
2025-03-05 10:01:57 +08:00
23 changed files with 165 additions and 123 deletions

View File

@@ -55,8 +55,8 @@ if "%command%"=="restart" (
set "webDir=%baseDir%\webapp"
set "logDir=%baseDir%\logs"
set "classpath=%baseDir%;%webDir%;%libDir%\*;%confDir%"
set "java-command=-Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 -Dspring.profiles.active=%profile% -Xms1024m
-Xmx1024m -cp %CLASSPATH% %MAIN_CLASS%"
set "property=-Dfile.encoding=UTF-8 -Duser.language=Zh -Duser.region=CN -Duser.timezone=GMT+08 -Dspring.profiles.active=%profile%"
set "java-command=%property% -Xms1024m -Xmx1024m -cp %CLASSPATH% %MAIN_CLASS%"
if not exist %logDir% mkdir %logDir%
start /B java %java-command% >nul 2>&1
timeout /t 10 >nul

View File

@@ -1,7 +1,7 @@
package com.tencent.supersonic.auth.authentication.interceptor;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.authentication.utils.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -16,7 +16,7 @@ public abstract class AuthenticationInterceptor implements HandlerInterceptor {
protected AuthenticationConfig authenticationConfig;
protected UserServiceImpl userServiceImpl;
protected UserService userService;
protected TokenService tokenService;

View File

@@ -3,7 +3,7 @@ package com.tencent.supersonic.auth.authentication.interceptor;
import com.tencent.supersonic.auth.api.authentication.annotation.AuthenticationIgnore;
import com.tencent.supersonic.auth.api.authentication.config.AuthenticationConfig;
import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.authentication.service.UserServiceImpl;
import com.tencent.supersonic.auth.api.authentication.service.UserService;
import com.tencent.supersonic.auth.authentication.utils.TokenService;
import com.tencent.supersonic.common.pojo.exception.AccessException;
import com.tencent.supersonic.common.util.ContextUtils;
@@ -16,12 +16,7 @@ import org.springframework.web.method.HandlerMethod;
import java.lang.reflect.Method;
import java.util.Optional;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_IS_ADMIN;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_DISPLAY_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_EMAIL;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_ID;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_NAME;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.TOKEN_USER_PASSWORD;
import static com.tencent.supersonic.auth.api.authentication.constant.UserConstants.*;
@Slf4j
public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor {
@@ -30,7 +25,7 @@ public class DefaultAuthenticationInterceptor extends AuthenticationInterceptor
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws AccessException {
authenticationConfig = ContextUtils.getBean(AuthenticationConfig.class);
userServiceImpl = ContextUtils.getBean(UserServiceImpl.class);
userService = ContextUtils.getBean(UserService.class);
tokenService = ContextUtils.getBean(TokenService.class);
if (!authenticationConfig.isEnabled()) {
return true;

View File

@@ -4,10 +4,13 @@ import com.google.common.base.Objects;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
import static com.tencent.supersonic.common.pojo.Constants.ASC_UPPER;
@Data
public class Order {
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@NotBlank(message = "Invalid order column")
private String column;

View File

@@ -1,25 +1,15 @@
# Use an official OpenJDK runtime as a parent image
FROM openjdk:21-jdk-bullseye
FROM supersonicbi/supersonic:0.9.10-SNAPSHOT
# Set the working directory in the container
WORKDIR /usr/src/app
# Delete old supersonic installation directory and the symbolic link
RUN rm -rf /usr/src/app/supersonic-standalone-0.9.10-SNAPSHOT
RUN rm -f /usr/src/app/supersonic-standalone-latest
# Argument to pass in the supersonic version at build time
ARG SUPERSONIC_VERSION
# Install necessary packages, including Postgres client
RUN apt-get update && apt-get install -y postgresql-client
# Install the vim editor.
RUN apt-get update && apt-get install -y vim && \
rm -rf /var/lib/apt/lists/*
# Update the package list and install iputils-ping.
RUN apt-get update && apt-get install -y iputils-ping
# 更新包列表并安装 dnsutils 包
RUN apt-get update && apt-get install -y dnsutils
# Copy the supersonic standalone zip file into the container
COPY assembly/build/supersonic-standalone-${SUPERSONIC_VERSION}.zip .

View File

@@ -12,7 +12,7 @@ services:
ports:
- "15432:5432"
# volumes:
# - postgres_data:/var/lib/postgresql
# - postgres_data:/var/lib/postgresql/data
networks:
- supersonic_network
dns:
@@ -21,7 +21,7 @@ services:
- 8.8.4.4
healthcheck:
test: ["CMD-SHELL", "sh -c 'pg_isready -U supersonic_user -d postgres'"]
interval: 30s
interval: 10s
timeout: 10s
retries: 5
@@ -62,4 +62,4 @@ services:
# supersonic_data:
networks:
supersonic_network:
supersonic_network:

View File

@@ -133,6 +133,10 @@
<groupId>io.trino</groupId>
<artifactId>trino-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
</dependency>
</dependencies>

View File

@@ -1,6 +1,7 @@
package com.tencent.supersonic.headless.core.translator;
import com.tencent.supersonic.common.calcite.SqlMergeWithUtils;
import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper;
import com.tencent.supersonic.common.pojo.enums.EngineType;
import com.tencent.supersonic.headless.api.pojo.response.QueryState;
import com.tencent.supersonic.headless.core.pojo.OntologyQuery;
@@ -73,7 +74,7 @@ public class DefaultSemanticTranslator implements SemanticTranslator {
String finalSql = null;
if (sqlQuery.isSupportWith()) {
EngineType engineType = queryStatement.getOntology().getDatabaseType();
if (!SqlMergeWithUtils.hasWith(engineType, ontologyOuterSql)) {
if (!SqlSelectHelper.hasWith(ontologyOuterSql)) {
finalSql = "with " + tables.stream()
.map(t -> String.format("%s as (%s)", t.getLeft(), t.getRight()))
.collect(Collectors.joining(",")) + "\n" + ontologyOuterSql;

View File

@@ -1,5 +1,6 @@
package com.tencent.supersonic.headless.core.translator.parser.calcite;
import com.google.common.collect.Sets;
import com.tencent.supersonic.common.calcite.Configuration;
import com.tencent.supersonic.common.pojo.enums.EngineType;
import com.tencent.supersonic.headless.api.pojo.Dimension;
@@ -9,17 +10,26 @@ import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp;
import com.tencent.supersonic.headless.api.pojo.response.DimSchemaResp;
import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp;
import com.tencent.supersonic.headless.api.pojo.response.ModelResp;
import com.tencent.supersonic.headless.core.pojo.*;
import com.tencent.supersonic.headless.core.pojo.JoinRelation;
import com.tencent.supersonic.headless.core.pojo.Ontology;
import com.tencent.supersonic.headless.core.pojo.OntologyQuery;
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
import com.tencent.supersonic.headless.core.translator.parser.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.sql.*;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.util.CollectionUtils;
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultUndirectedGraph;
import java.util.*;
import java.util.stream.Collectors;
@@ -37,6 +47,8 @@ public class SqlBuilder {
public String buildOntologySql(QueryStatement queryStatement) throws Exception {
OntologyQuery ontologyQuery = queryStatement.getOntologyQuery();
Ontology ontology = queryStatement.getOntology();
if (ontologyQuery.getLimit() == null) {
ontologyQuery.setLimit(0L);
}
@@ -46,7 +58,14 @@ public class SqlBuilder {
throw new Exception("data model not found");
}
TableView tableView = render(ontologyQuery, new ArrayList<>(dataModels), scope, schema);
TableView tableView;
if (!CollectionUtils.isEmpty(ontology.getJoinRelations()) && dataModels.size() > 1) {
Set<ModelResp> models = probeRelatedModels(dataModels, queryStatement.getOntology());
tableView = render(ontologyQuery, models, scope, schema);
} else {
tableView = render(ontologyQuery, dataModels, scope, schema);
}
SqlNode parserNode = tableView.build();
DatabaseResp database = queryStatement.getOntology().getDatabase();
EngineType engineType = EngineType.fromString(database.getType());
@@ -54,7 +73,61 @@ public class SqlBuilder {
return SemanticNode.getSql(parserNode, engineType);
}
private SqlNode optimizeParseNode(SqlNode parserNode, EngineType engineType) {
private Set<ModelResp> probeRelatedModels(Set<ModelResp> dataModels, Ontology ontology) {
List<JoinRelation> joinRelations = ontology.getJoinRelations();
Graph<String, DefaultEdge> graph = buildGraph(joinRelations);
DijkstraShortestPath<String, DefaultEdge> dijkstraAlg = new DijkstraShortestPath<>(graph);
Set<String> queryModels =
dataModels.stream().map(ModelResp::getName).collect(Collectors.toSet());
GraphPath<String, DefaultEdge> selectedGraphPath = null;
for (String fromModel : queryModels) {
for (String toModel : queryModels) {
if (fromModel != toModel) {
GraphPath<String, DefaultEdge> path = dijkstraAlg.getPath(fromModel, toModel);
if (isGraphPathContainsAll(path, queryModels)) {
selectedGraphPath = path;
break;
}
}
}
}
if (selectedGraphPath == null) {
return dataModels;
}
Set<String> modelNames = Sets.newHashSet();
for (DefaultEdge edge : selectedGraphPath.getEdgeList()) {
modelNames.add(selectedGraphPath.getGraph().getEdgeSource(edge));
modelNames.add(selectedGraphPath.getGraph().getEdgeTarget(edge));
}
return modelNames.stream().map(m -> ontology.getModelMap().get(m))
.collect(Collectors.toSet());
}
private boolean isGraphPathContainsAll(GraphPath<String, DefaultEdge> graphPath,
Set<String> vertex) {
Set<String> allVertex = Sets.newHashSet();
for (DefaultEdge edge : graphPath.getEdgeList()) {
allVertex.add(graphPath.getGraph().getEdgeSource(edge));
allVertex.add(graphPath.getGraph().getEdgeTarget(edge));
}
Collection<String> intersect =
org.apache.commons.collections.CollectionUtils.intersection(vertex, allVertex);
return intersect.size() == vertex.size() ? true : false;
}
private Graph<String, DefaultEdge> buildGraph(List<JoinRelation> joinRelations) {
Graph<String, DefaultEdge> directedGraph = new DefaultUndirectedGraph<>(DefaultEdge.class);
for (JoinRelation joinRelation : joinRelations) {
directedGraph.addVertex(joinRelation.getLeft());
directedGraph.addVertex(joinRelation.getRight());
directedGraph.addEdge(joinRelation.getLeft(), joinRelation.getRight());
}
return directedGraph;
}
private SqlNode optimizeParseNode(SqlNode parserNode, EngineType engineType)
throws SqlParseException {
if (Objects.isNull(schema.getRuntimeOptions())
|| Objects.isNull(schema.getRuntimeOptions().getEnableOptimize())
|| !schema.getRuntimeOptions().getEnableOptimize()) {
@@ -62,14 +135,10 @@ public class SqlBuilder {
}
SqlNode optimizeNode = null;
try {
SqlNode sqlNode = SqlParser.create(SemanticNode.getSql(parserNode, engineType),
Configuration.getParserConfig(engineType)).parseStmt();
if (Objects.nonNull(sqlNode)) {
optimizeNode = SemanticNode.optimize(scope, schema, sqlNode, engineType);
}
} catch (Exception e) {
log.error("optimize error {}", e);
SqlNode sqlNode = SqlParser.create(SemanticNode.getSql(parserNode, engineType),
Configuration.getParserConfig(engineType)).parseStmt();
if (Objects.nonNull(sqlNode)) {
optimizeNode = SemanticNode.optimize(scope, schema, sqlNode, engineType);
}
if (Objects.nonNull(optimizeNode)) {
@@ -79,7 +148,7 @@ public class SqlBuilder {
return parserNode;
}
private TableView render(OntologyQuery ontologyQuery, List<ModelResp> dataModels,
private TableView render(OntologyQuery ontologyQuery, Set<ModelResp> dataModels,
SqlValidatorScope scope, S2CalciteSchema schema) throws Exception {
SqlNode left = null;
TableView leftTable = null;
@@ -88,8 +157,7 @@ public class SqlBuilder {
Map<String, String> beforeModels = new HashMap<>();
EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType());
for (int i = 0; i < dataModels.size(); i++) {
final ModelResp dataModel = dataModels.get(i);
for (ModelResp dataModel : dataModels) {
final Set<DimSchemaResp> queryDimensions =
ontologyQuery.getDimensionsByModel(dataModel.getName());
final Set<MetricSchemaResp> queryMetrics =
@@ -141,7 +209,8 @@ public class SqlBuilder {
SqlLiteral sqlLiteral = SemanticNode.getJoinSqlLiteral("");
JoinRelation matchJoinRelation = getMatchJoinRelation(before, rightTable, schema);
SqlNode joinRelationCondition;
if (!CollectionUtils.isEmpty(matchJoinRelation.getJoinCondition())) {
if (!org.apache.commons.collections.CollectionUtils
.isEmpty(matchJoinRelation.getJoinCondition())) {
sqlLiteral = SemanticNode.getJoinSqlLiteral(matchJoinRelation.getJoinType());
joinRelationCondition = getCondition(matchJoinRelation, scope, engineType);
condition = joinRelationCondition;
@@ -170,12 +239,19 @@ public class SqlBuilder {
} else if (joinRelation.getLeft()
.equalsIgnoreCase(tableView.getDataModel().getName())
&& before.containsKey(joinRelation.getRight())) {
matchJoinRelation.setJoinCondition(joinRelation.getJoinCondition().stream()
List<Triple<String, String, String>> candidateJoinCon = joinRelation
.getJoinCondition().stream()
.map(r -> Triple.of(
before.get(joinRelation.getRight()) + "." + r.getRight(),
r.getMiddle(), tableView.getAlias() + "." + r.getLeft()))
.collect(Collectors.toList()));
matchJoinRelation.setJoinType(joinRelation.getJoinType());
.collect(Collectors.toList());
// added by jerryjzhang on 20250214
// use the one with the most conditions to join left and right tables
if (matchJoinRelation.getJoinCondition() == null || candidateJoinCon
.size() > matchJoinRelation.getJoinCondition().size()) {
matchJoinRelation.setJoinCondition(candidateJoinCon);
matchJoinRelation.setJoinType(joinRelation.getJoinType());
}
}
}
}

View File

@@ -2,6 +2,7 @@ package com.tencent.supersonic.headless.server.rest;
import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.enums.StatusEnum;
import com.tencent.supersonic.headless.api.pojo.MetaFilter;
import com.tencent.supersonic.headless.api.pojo.request.DataSetReq;
import com.tencent.supersonic.headless.api.pojo.response.DataSetResp;
@@ -51,6 +52,7 @@ public class DataSetController {
public List<DataSetResp> getDataSetList(@RequestParam("domainId") Long domainId) {
MetaFilter metaFilter = new MetaFilter();
metaFilter.setDomainId(domainId);
metaFilter.setStatus(StatusEnum.ONLINE.getCode());
return dataSetService.getDataSetList(metaFilter);
}

View File

@@ -56,9 +56,9 @@ public class DataSetServiceImpl extends ServiceImpl<DataSetDOMapper, DataSetDO>
public DataSetResp save(DataSetReq dataSetReq, User user) {
dataSetReq.createdBy(user.getName());
DataSetDO dataSetDO = convert(dataSetReq);
dataSetDO.setStatus(StatusEnum.ONLINE.getCode());
dataSetDO.setStatus(dataSetReq.getStatus() != null ? dataSetReq.getStatus()
: StatusEnum.ONLINE.getCode());
DataSetResp dataSetResp = convert(dataSetDO);
// conflictCheck(dataSetResp);
save(dataSetDO);
dataSetResp.setId(dataSetDO.getId());
return dataSetResp;

View File

@@ -4,9 +4,9 @@ spring:
url: jdbc:postgresql://${DB_HOST}:${DB_PORT:5432}/${DB_NAME}?stringtype=unspecified
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
sql:
init:
continue-on-error: true
mode: always
username: ${DB_USERNAME}
password: ${DB_PASSWORD}

View File

@@ -5,21 +5,21 @@ CREATE TABLE IF NOT EXISTS `s2_agent` (
`examples` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
`status` tinyint DEFAULT NULL,
`model` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`tool_config` varchar(6000) COLLATE utf8_unicode_ci DEFAULT NULL,
`llm_config` varchar(2000) COLLATE utf8_unicode_ci DEFAULT NULL,
`tool_config` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
`llm_config` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
`chat_model_config` text COLLATE utf8_unicode_ci DEFAULT NULL,
`visual_config` varchar(2000) COLLATE utf8_unicode_ci DEFAULT NULL,
`visual_config` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
`enable_search` tinyint DEFAULT 1,
`enable_feedback` tinyint DEFAULT 1,
`created_by` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_by` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`admin` varchar(3000) DEFAULT NULL COMMENT '管理员',
`admin_org` varchar(3000) DEFAULT NULL COMMENT '管理员组织',
`admin` varchar(1000) DEFAULT NULL COMMENT '管理员',
`admin_org` varchar(1000) DEFAULT NULL COMMENT '管理员组织',
`is_open` tinyint DEFAULT NULL COMMENT '是否公开',
`viewer` varchar(3000) DEFAULT NULL COMMENT '可用用户',
`view_org` varchar(3000) DEFAULT NULL COMMENT '可用组织',
`viewer` varchar(1000) DEFAULT NULL COMMENT '可用用户',
`view_org` varchar(1000) DEFAULT NULL COMMENT '可用组织',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@@ -26,7 +26,7 @@
</parent>
<properties>
<revision>0.9.10-SNAPSHOT</revision>
<revision>1.0.0-SNAPSHOT</revision>
<java.source.version>21</java.source.version>
<java.target.version>21</java.target.version>
<maven.compiler.source>21</maven.compiler.source>
@@ -82,6 +82,7 @@
<spotless.skip>false</spotless.skip>
<stax2.version>4.2.1</stax2.version>
<aws-java-sdk.version>1.12.780</aws-java-sdk.version>
<jgrapht.version>1.5.2</jgrapht.version>
</properties>
<dependencyManagement>
@@ -236,6 +237,11 @@
<artifactId>aws-java-sdk</artifactId>
<version>${aws-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>${jgrapht.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -155,29 +155,8 @@ export default defineConfig({
//================ pro 插件配置 =================
presets: ['umi-presets-pro'],
/**
* @name openAPI 插件的配置
* @description 基于 openapi 的规范生成serve 和mock能减少很多样板代码
* @doc https://pro.ant.design/zh-cn/docs/openapi/
*/
// openAPI: [
// {
// requestLibPath: "import { request } from '@umijs/max'",
// // 或者使用在线的版本
// // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
// schemaPath: join(__dirname, 'oneapi.json'),
// mock: false,
// },
// {
// requestLibPath: "import { request } from '@umijs/max'",
// schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
// projectName: 'swagger',
// },
// ],
// 将insights-flow相关包排除出mfsu编译在pnpm link 模式下保持热更新
mfsu: {
strategy: 'normal',
// exclude: ['supersonic-insights-flow-components', 'supersonic-insights-flow-core'],
},
requestRecord: {},
exportStatic: {},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -147,8 +147,8 @@ export const layout: RunTimeLayoutConfig = (params) => {
height: location.pathname.includes('chat') ? 'calc(100vh - 56px)' : undefined,
}}
>
<AppPage dom={dom} />
{/* {dom} */}
{/* <AppPage dom={dom} /> */}
{dom}
{history.location.pathname !== '/chat' && !isMobile && (
<Copilot token={getToken() || ''} isDeveloper />
)}

View File

@@ -1,9 +1,9 @@
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { Input, message, Popconfirm, Tooltip, Row, Col, Button, Menu } from 'antd';
import { Input, message, Popconfirm, Tooltip, Row, Col, Button, Menu, MenuProps } from 'antd';
import type { DataNode } from 'antd/lib/tree';
import { useEffect, useState } from 'react';
import type { FC } from 'react';
import { useModel } from '@umijs/max';
import { useModel, history } from '@umijs/max';
import { createDomain, updateDomain, deleteDomain } from '../service';
import DomainInfoForm from './DomainInfoForm';
import styles from './style.less';
@@ -71,6 +71,7 @@ const DomainListTree: FC<DomainListProps> = ({
message.success('编辑分类成功');
setProjectInfoModalVisible(false);
onTreeDataUpdate?.();
window.location.reload();
} else {
message.error(res.msg);
}
@@ -78,10 +79,13 @@ const DomainListTree: FC<DomainListProps> = ({
const domainSubmit = async (values: any) => {
if (values.modelType === 'add') {
const { code, data } = await createDomain(values);
// if (code === 200 && values.type === 'top') {
// await createDefaultModelSet(data.id);
// }
const { code, data, msg } = await createDomain(values);
if (code === 200) {
history.push(`/model/domain/${data.id}`);
window.location.reload();
} else {
message.error(msg);
}
} else if (values.modelType === 'edit') {
await editProject(values);
}
@@ -95,6 +99,7 @@ const DomainListTree: FC<DomainListProps> = ({
message.success('删除成功');
setProjectInfoModalVisible(false);
onTreeDataUpdate?.();
window.location.reload();
} else {
message.error(res.msg);
}
@@ -104,12 +109,7 @@ const DomainListTree: FC<DomainListProps> = ({
const { id, name, path, hasEditPermission, parentId, hasModel } = node as any;
const type = parentId === 0 ? 'top' : 'normal';
return (
<div
className={styles.projectItem}
// onClick={() => {
// handleSelect(id);
// }}
>
<div className={styles.projectItem}>
<span className={styles.projectItemTitle}>{name}</span>
{createDomainBtnVisible && hasEditPermission && (
<span className={`${styles.operation} ${styles.rowHover} `}>
@@ -175,13 +175,12 @@ const DomainListTree: FC<DomainListProps> = ({
return {
key: domain.id,
label: titleRender(domain),
// icon: <AppstoreOutlined />,
};
});
const getLevelKeys = (items1: LevelKeysProps[]) => {
const getLevelKeys = (items1: any[]) => {
const key: Record<string, number> = {};
const func = (items2: LevelKeysProps[], level = 1) => {
const func = (items2: any[], level = 1) => {
items2.forEach((item) => {
if (item.key) {
key[item.key] = level;
@@ -194,7 +193,7 @@ const DomainListTree: FC<DomainListProps> = ({
func(items1);
return key;
};
const levelKeys = getLevelKeys(items as LevelKeysProps[]);
const levelKeys = getLevelKeys(items as any[]);
const [stateOpenKeys, setStateOpenKeys] = useState(['2', '23']);
const onOpenChange: MenuProps['onOpenChange'] = (openKeys) => {

View File

@@ -82,6 +82,7 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
});
if (code === 200) {
onModelChange?.();
window.location.reload();
return;
}
message.error(msg);
@@ -198,6 +199,7 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
const { code, msg } = await deleteModel(record.id);
if (code === 200) {
onModelChange?.();
window.location.reload();
} else {
message.error(msg);
}
@@ -292,6 +294,7 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
onModelChange?.();
setIsEditing(false);
setCreateDataSourceModalOpen(false);
window.location.reload();
}}
onCancel={() => {
setIsEditing(false);

View File

@@ -1,11 +1,8 @@
import { message } from 'antd';
import React, { useEffect, useState } from 'react';
import { history, useParams, useModel, Outlet } from '@umijs/max';
import DomainListTree from './components/DomainList';
import styles from './components/style.less';
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import React, { useEffect } from 'react';
import { useParams, useModel, Outlet } from '@umijs/max';
import { ISemantic } from './data';
import { getDomainList, getDataSetList, getModelDetail } from './service';
import { getDomainList, getModelDetail } from './service';
import PageBreadcrumb from './PageBreadcrumb';
type Props = {};
@@ -17,20 +14,10 @@ const SemanticModel: React.FC<Props> = ({}) => {
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const databaseModel = useModel('SemanticModel.databaseData');
const metricModel = useModel('SemanticModel.metricData');
const { setSelectDomain, setDomainList, selectDomainId } = domainModel;
const { selectModel, setSelectModel, setModelTableHistoryParams, MrefreshModelList } = modelModel;
const { setSelectDomain, setDomainList } = domainModel;
const { selectModel, setSelectModel } = modelModel;
const { MrefreshDatabaseList } = databaseModel;
const { selectMetric, setSelectMetric } = metricModel;
// useEffect(() => {
// return () => {
// setSelectMetric(undefined);
// }
// }, [])
const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => {
const targetNode = domainList.filter((item: any) => {
return `${item.id}` === domainId;
@@ -40,9 +27,7 @@ const SemanticModel: React.FC<Props> = ({}) => {
return item.parentId === 0;
})[0];
if (firstRootNode) {
const { id } = firstRootNode;
setSelectDomain(firstRootNode);
// pushUrlMenu(id, menuKey);
}
} else {
setSelectDomain(targetNode);
@@ -87,7 +72,6 @@ const SemanticModel: React.FC<Props> = ({}) => {
</div>
<div>
<Outlet />
{/* <OverviewContainer /> */}
</div>
</div>
);

View File

@@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
import { useModel } from '@umijs/max';
export default function Domain() {
const [selectDomain, setSelectDomain] = useState<ISemantic.IDomainItem>(
const [selectDomain, setSelectDomain] = useState<ISemantic.IDomainItem | undefined>(
{} as ISemantic.IDomainItem,
);
const [selectDataSet, setSelectDataSet] = useState<ISemantic.IDatasetItem>();