15 Commits

Author SHA1 Message Date
WDEP
a5d1d7a899 Merge e083b13193 into be8b56bdde 2025-04-30 02:25:50 +00:00
supersonicbi
be8b56bdde (improvement)(common)Only expose OPEN_AI/OLLAMA/DIFY chat model providers.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-27 12:59:23 +08:00
supersonicbi
9f2c0c7699 (improvement)(headless)Add default jdbc URL for typical database types. 2025-04-27 12:58:36 +08:00
supersonicbi
c1fa9d7442 (improvement)(headless)Support ordering in chat model and database tables. 2025-04-27 12:57:25 +08:00
superhero
0d5da763b3 Merge pull request #2234 from beat4ocean/master
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
[Fix][headless-fe] Error when copying access token
2025-04-27 09:42:42 +08:00
beat4ocean
d1b4863a27 [Fix][headless-fe] Error when copying access token 2025-04-26 10:31:26 +08:00
supersonicbi
dce9a8a58c (fix)(chat)Fix NPE in getParseInfo.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-25 20:41:04 +08:00
jerryjzhang
fbf048cb00 (fix)(headless)Fix show type and retrieve issues.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-21 14:41:31 +08:00
jerryjzhang
48a8f69cca [fix][heaadless]Use columnName as fieldName.
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-15 21:25:04 +08:00
jerryjzhang
ecdf65da3e (fix)(headless)Fix bizName and name NPE issue.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-04-14 21:09:37 +08:00
poncheen
5585b9e222 Fix/ts errors in fe (#2218)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-11 20:58:35 +08:00
Antgeek
97710a90c4 (improve)(benchmark) improve benchmark, add analysis of parsing results (#2215)
Some checks failed
supersonic CentOS CI / build (21) (push) Has been cancelled
supersonic mac CI / build (21) (push) Has been cancelled
supersonic ubuntu CI / build (21) (push) Has been cancelled
supersonic windows CI / build (21) (push) Has been cancelled
2025-04-10 08:57:25 +08:00
jerryjzhang
0ab7643299 [fix][heaadless]Optimize logic of determine number types.
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-04-10 00:25:56 +08:00
Antgeek
d2aa73b85e (fix)(headless) fix ModelCreateForm.tsx error (#2214)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-04-08 20:49:37 +08:00
chixiaopao
8828964e53 (fix)(headless) fix dfs NullPointerException when model is null. (#2212)
Some checks are pending
supersonic CentOS CI / build (21) (push) Waiting to run
supersonic mac CI / build (21) (push) Waiting to run
supersonic ubuntu CI / build (21) (push) Waiting to run
supersonic windows CI / build (21) (push) Waiting to run
2025-04-07 20:55:41 +08:00
34 changed files with 428 additions and 321 deletions

3
.gitignore vendored
View File

@@ -20,4 +20,5 @@ chm_db/
__pycache__/
/dict
assembly/build/*-SNAPSHOT
**/node_modules/
**/node_modules/
benchmark/res/

View File

@@ -15,6 +15,68 @@ import requests
import time
import jwt
import traceback
import os
from datetime import datetime
class DataFrameAppender:
def __init__(self,file_name = "output"):
# 定义表头
columns = ['问题', '解析状态', '解析耗时', '执行状态', '执行耗时', '总耗时']
# 创建只有表头的 DataFrame
self.df = pd.DataFrame(columns=columns)
self.file_name = file_name
def append_data(self, new_data):
# 假设 new_data 是一维数组,将其转换为字典
columns = ['问题', '解析状态', '解析耗时', '执行状态', '执行耗时', '总耗时']
new_dict = dict(zip(columns, new_data))
# 使用 loc 方法追加数据
self.df.loc[len(self.df)] = new_dict
def print_analysis_result(self):
# 测试样例总数
total_samples = len(self.df)
# 解析成功数量
parse_success_count = (self.df['解析状态'] == '解析成功').sum()
# 执行成功数量
execute_success_count = (self.df['执行状态'] == '执行成功').sum()
# 解析平均耗时,保留两位小数
avg_parse_time = round(self.df['解析耗时'].mean(), 2)
# 执行平均耗时,保留两位小数
avg_execute_time = round(self.df['执行耗时'].mean(), 2)
# 总平均耗时,保留两位小数
avg_total_time = round(self.df['总耗时'].mean(), 2)
# 最长耗时,保留两位小数
max_time = round(self.df['总耗时'].max(), 2)
# 最短耗时,保留两位小数
min_time = round(self.df['总耗时'].min(), 2)
print(f"测试样例总数 : {total_samples}")
print(f"解析成功数量 : {parse_success_count}")
print(f"执行成功数量 : {execute_success_count}")
print(f"解析平均耗时 : {avg_parse_time}")
print(f"执行平均耗时 : {avg_execute_time}")
print(f"总平均耗时 : {avg_total_time}")
print(f"最长耗时 : {max_time}")
print(f"最短耗时 : {min_time}")
def write_to_csv(self):
# 检查 data 文件夹是否存在,如果不存在则创建
if not os.path.exists('res'):
os.makedirs('res')
# 获取当前时间戳
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
# 生成带时间戳的文件名
file_path = os.path.join('res', f'{self.file_name}_{timestamp}.csv')
self.df.to_csv(file_path, index=False)
print(f"测试结果已保存到 {file_path}")
class BatchTest:
def __init__(self, url, agentId, chatId, userName):
@@ -70,18 +132,35 @@ class BatchTest:
def benchmark(url:str, agentId:str, chatId:str, filePath:str, userName:str):
batch_test = BatchTest(url, agentId, chatId, userName)
df = batch_test.read_question_from_csv(filePath)
appender = DataFrameAppender(os.path.basename(filePath))
for index, row in df.iterrows():
question = row['question']
print('start to ask question:', question)
# 捕获异常,防止程序中断
try:
parse_resp = batch_test.parse(question)
batch_test.execute(agentId, question, parse_resp['data']['queryId'])
parse_status = '解析失败'
if parse_resp.get('data').get('errorMsg') is None:
parse_status = '解析成功'
parse_cost = parse_resp.get('data').get('parseTimeCost').get('parseTime')
execute_resp = batch_test.execute(agentId, question, parse_resp['data']['queryId'])
execute_status = '执行失败'
execute_cost = 0
if parse_status == '解析成功' and execute_resp.get('data').get('errorMsg') is None:
execute_status = '执行成功'
execute_cost = execute_resp.get('data').get('queryTimeCost')
res = [question.replace(',', '#'),parse_status,parse_cost/1000,execute_status,execute_cost/1000,(parse_cost+execute_cost)/1000]
appender.append_data(res)
except Exception as e:
print('error:', e)
traceback.print_exc()
continue
time.sleep(1)
# 打印分析结果
appender.print_analysis_result()
# 分析明细输出
appender.write_to_csv()
if __name__ == '__main__':

View File

@@ -233,6 +233,10 @@ public class ChatManageServiceImpl implements ChatManageService {
@Override
public SemanticParseInfo getParseInfo(Long questionId, int parseId) {
ChatParseDO chatParseDO = chatQueryRepository.getParseInfo(questionId, parseId);
return JSONObject.parseObject(chatParseDO.getParseInfo(), SemanticParseInfo.class);
if (chatParseDO == null) {
return null;
} else {
return JSONObject.parseObject(chatParseDO.getParseInfo(), SemanticParseInfo.class);
}
}
}

View File

@@ -2,15 +2,7 @@ package com.tencent.supersonic.common.pojo;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import dev.langchain4j.provider.AzureModelFactory;
import dev.langchain4j.provider.DashscopeModelFactory;
import dev.langchain4j.provider.DifyModelFactory;
import dev.langchain4j.provider.LocalAiModelFactory;
import dev.langchain4j.provider.ModelProvider;
import dev.langchain4j.provider.OllamaModelFactory;
import dev.langchain4j.provider.OpenAiModelFactory;
import dev.langchain4j.provider.QianfanModelFactory;
import dev.langchain4j.provider.ZhipuModelFactory;
import dev.langchain4j.provider.*;
import java.util.ArrayList;
import java.util.List;
@@ -21,7 +13,7 @@ public class ChatModelParameters {
public static final Parameter CHAT_MODEL_PROVIDER =
new Parameter("provider", ModelProvider.DEMO_CHAT_MODEL.getProvider(), "接口协议", "",
"list", MODULE_NAME, getCandidateValues());
"list", MODULE_NAME, getCandidateProviders());
public static final Parameter CHAT_MODEL_BASE_URL =
new Parameter("baseUrl", ModelProvider.DEMO_CHAT_MODEL.getBaseUrl(), "BaseUrl", "",
@@ -58,37 +50,22 @@ public class ChatModelParameters {
CHAT_MODEL_ENABLE_SEARCH, CHAT_MODEL_TEMPERATURE, CHAT_MODEL_TIMEOUT);
}
private static List<String> getCandidateValues() {
private static List<String> getCandidateProviders() {
return Lists.newArrayList(OpenAiModelFactory.PROVIDER, OllamaModelFactory.PROVIDER,
QianfanModelFactory.PROVIDER, ZhipuModelFactory.PROVIDER,
LocalAiModelFactory.PROVIDER, DashscopeModelFactory.PROVIDER,
AzureModelFactory.PROVIDER, DifyModelFactory.PROVIDER);
DifyModelFactory.PROVIDER);
}
private static List<Parameter.Dependency> getBaseUrlDependency() {
return getDependency(CHAT_MODEL_PROVIDER.getName(), getCandidateValues(),
return getDependency(CHAT_MODEL_PROVIDER.getName(), getCandidateProviders(),
ImmutableMap.of(OpenAiModelFactory.PROVIDER, OpenAiModelFactory.DEFAULT_BASE_URL,
AzureModelFactory.PROVIDER, AzureModelFactory.DEFAULT_BASE_URL,
OllamaModelFactory.PROVIDER, OllamaModelFactory.DEFAULT_BASE_URL,
QianfanModelFactory.PROVIDER, QianfanModelFactory.DEFAULT_BASE_URL,
ZhipuModelFactory.PROVIDER, ZhipuModelFactory.DEFAULT_BASE_URL,
LocalAiModelFactory.PROVIDER, LocalAiModelFactory.DEFAULT_BASE_URL,
DashscopeModelFactory.PROVIDER, DashscopeModelFactory.DEFAULT_BASE_URL,
DifyModelFactory.PROVIDER, DifyModelFactory.DEFAULT_BASE_URL));
}
private static List<Parameter.Dependency> getApiKeyDependency() {
return getDependency(CHAT_MODEL_PROVIDER.getName(),
Lists.newArrayList(OpenAiModelFactory.PROVIDER, QianfanModelFactory.PROVIDER,
ZhipuModelFactory.PROVIDER, LocalAiModelFactory.PROVIDER,
AzureModelFactory.PROVIDER, DashscopeModelFactory.PROVIDER,
DifyModelFactory.PROVIDER),
Lists.newArrayList(OpenAiModelFactory.PROVIDER, DifyModelFactory.PROVIDER),
ImmutableMap.of(OpenAiModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), QianfanModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), ZhipuModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), LocalAiModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), AzureModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), DashscopeModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey(), DifyModelFactory.PROVIDER,
ModelProvider.DEMO_CHAT_MODEL.getApiKey()));
}
@@ -100,14 +77,9 @@ public class ChatModelParameters {
}
private static List<Parameter.Dependency> getModelNameDependency() {
return getDependency(CHAT_MODEL_PROVIDER.getName(), getCandidateValues(),
return getDependency(CHAT_MODEL_PROVIDER.getName(), getCandidateProviders(),
ImmutableMap.of(OpenAiModelFactory.PROVIDER, OpenAiModelFactory.DEFAULT_MODEL_NAME,
OllamaModelFactory.PROVIDER, OllamaModelFactory.DEFAULT_MODEL_NAME,
QianfanModelFactory.PROVIDER, QianfanModelFactory.DEFAULT_MODEL_NAME,
ZhipuModelFactory.PROVIDER, ZhipuModelFactory.DEFAULT_MODEL_NAME,
LocalAiModelFactory.PROVIDER, LocalAiModelFactory.DEFAULT_MODEL_NAME,
AzureModelFactory.PROVIDER, AzureModelFactory.DEFAULT_MODEL_NAME,
DashscopeModelFactory.PROVIDER, DashscopeModelFactory.DEFAULT_MODEL_NAME,
DifyModelFactory.PROVIDER, DifyModelFactory.DEFAULT_MODEL_NAME));
}

View File

@@ -14,6 +14,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -31,7 +32,7 @@ public class ChatModelServiceImpl extends ServiceImpl<ChatModelMapper, ChatModel
return true;
}
return false;
}).collect(Collectors.toList());
}).sorted(Comparator.comparingLong(ChatModel::getId)).collect(Collectors.toList());
}
@Override

View File

@@ -14,9 +14,9 @@ public class DefaultParametersBuilder implements DbParametersBuilder {
public List<DatabaseParameter> build() {
List<DatabaseParameter> databaseParameters = new ArrayList<>();
DatabaseParameter host = new DatabaseParameter();
host.setComment("");
host.setComment("JDBC连");
host.setName("url");
host.setPlaceholder("请输入链接");
host.setPlaceholder("请输入JDBC连接串");
databaseParameters.add(host);
DatabaseParameter userName = new DatabaseParameter();

View File

@@ -15,9 +15,10 @@ public class MysqlParametersBuilder implements DbParametersBuilder {
public List<DatabaseParameter> build() {
List<DatabaseParameter> databaseParameters = new ArrayList<>();
DatabaseParameter host = new DatabaseParameter();
host.setComment("");
host.setComment("JDBC连");
host.setName("url");
host.setPlaceholder("请输入链接");
host.setPlaceholder("请输入JDBC连接串");
host.setValue("jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf-8");
databaseParameters.add(host);
DatabaseParameter version = new DatabaseParameter();

View File

@@ -3,6 +3,7 @@ package com.tencent.supersonic.headless.server.pojo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
@@ -11,6 +12,27 @@ public class PostgresqlParametersBuilder extends DefaultParametersBuilder {
@Override
public List<DatabaseParameter> build() {
return super.build();
List<DatabaseParameter> databaseParameters = new ArrayList<>();
DatabaseParameter host = new DatabaseParameter();
host.setComment("JDBC连接");
host.setValue("jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf-8&useSSL");
host.setName("url");
host.setPlaceholder("请输入JDBC连接串");
databaseParameters.add(host);
DatabaseParameter userName = new DatabaseParameter();
userName.setComment("用户名");
userName.setName("username");
userName.setPlaceholder("请输入用户名");
databaseParameters.add(userName);
DatabaseParameter password = new DatabaseParameter();
password.setComment("密码");
password.setName("password");
password.setPlaceholder("请输入密码");
password.setRequire(false);
databaseParameters.add(password);
return databaseParameters;
}
}

View File

@@ -3,6 +3,7 @@ package com.tencent.supersonic.headless.server.pojo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
@@ -11,6 +12,26 @@ public class StarrocksParametersBuilder extends DefaultParametersBuilder {
@Override
public List<DatabaseParameter> build() {
return super.build();
}
List<DatabaseParameter> databaseParameters = new ArrayList<>();
DatabaseParameter host = new DatabaseParameter();
host.setComment("JDBC连接");
host.setValue("jdbc:mysql://localhost:3306/dbname");
host.setName("url");
host.setPlaceholder("请输入JDBC连接串");
databaseParameters.add(host);
DatabaseParameter userName = new DatabaseParameter();
userName.setComment("用户名");
userName.setName("username");
userName.setPlaceholder("请输入用户名");
databaseParameters.add(userName);
DatabaseParameter password = new DatabaseParameter();
password.setComment("密码");
password.setName("password");
password.setPlaceholder("请输入密码");
password.setRequire(false);
databaseParameters.add(password);
return databaseParameters; }
}

View File

@@ -34,10 +34,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@@ -82,6 +79,7 @@ public class DatabaseServiceImpl extends ServiceImpl<DatabaseDOMapper, DatabaseD
public List<DatabaseResp> getDatabaseList(User user) {
List<DatabaseResp> databaseResps = list().stream().map(DatabaseConverter::convert)
.filter(database -> filterByAuth(database, user, AuthType.VIEWER))
.sorted(Comparator.comparingLong(DatabaseResp::getId))
.collect(Collectors.toList());
fillPermission(databaseResps, user);
return databaseResps;

View File

@@ -60,6 +60,10 @@ public class RetrieveServiceImpl implements RetrieveService {
@Override
public List<SearchResult> retrieve(QueryNLReq queryNLReq) {
if (CollectionUtils.isEmpty(queryNLReq.getDataSetIds())) {
return Collections.emptyList();
}
String queryText = queryNLReq.getQueryText();
// 1. Get meta info

View File

@@ -48,6 +48,9 @@ public class ModelClusterBuilder {
private static void dfs(ModelSchemaResp model, Map<Long, ModelSchemaResp> modelMap,
Set<Long> visited, Set<Long> modelCluster) {
if (Objects.isNull(model)) {
return;
}
visited.add(model.getId());
modelCluster.add(model.getId());
for (Long neighborId : model.getModelClusterSet()) {

View File

@@ -145,8 +145,9 @@ public class ModelConverter {
public static ModelReq convert(ModelSchema modelSchema, ModelBuildReq modelBuildReq,
String tableName) {
ModelReq modelReq = new ModelReq();
modelReq.setName(modelBuildReq.getName());
modelReq.setBizName(modelBuildReq.getBizName());
modelReq.setName(modelBuildReq.getName() != null ? modelBuildReq.getName() : tableName);
modelReq.setBizName(
modelBuildReq.getBizName() != null ? modelBuildReq.getBizName() : tableName);
modelReq.setDatabaseId(modelBuildReq.getDatabaseId());
modelReq.setDomainId(modelBuildReq.getDomainId());
ModelDetail modelDetail = new ModelDetail();
@@ -160,7 +161,7 @@ public class ModelConverter {
List<Field> fields = new ArrayList<>();
for (SemanticColumn semanticColumn : modelSchema.getSemanticColumns()) {
FieldType fieldType = semanticColumn.getFiledType();
fields.add(new Field(semanticColumn.getName(), semanticColumn.getDataType()));
fields.add(new Field(semanticColumn.getColumnName(), semanticColumn.getDataType()));
if (getIdentifyType(fieldType) != null) {
Identify identify = new Identify(semanticColumn.getName(),

View File

@@ -135,13 +135,10 @@ public class QueryUtils {
if (StringUtils.isBlank(type)) {
return false;
}
return type.equalsIgnoreCase("int") || type.equalsIgnoreCase("bigint")
|| type.equalsIgnoreCase("tinyint") || type.equalsIgnoreCase("smallint")
return type.toLowerCase().endsWith("int") || type.toLowerCase().startsWith("int")
|| type.equalsIgnoreCase("float") || type.equalsIgnoreCase("double")
|| type.equalsIgnoreCase("real") || type.equalsIgnoreCase("numeric")
|| type.toLowerCase().startsWith("decimal") || type.toLowerCase().startsWith("uint")
|| type.toLowerCase().startsWith("int")
|| type.toLowerCase().equalsIgnoreCase("decfloat");
|| type.toLowerCase().startsWith("decimal") || type.equalsIgnoreCase("decfloat");
}
private String getName(String nameEn) {

View File

@@ -1,9 +1,9 @@
import { ProLayoutProps } from '@ant-design/pro-components';
const Settings: ProLayoutProps & {
export type DefaultSetting = ProLayoutProps & {
pwa?: boolean;
logo?: string;
} = {
};
const Settings: DefaultSetting = {
navTheme: 'light',
colorPrimary: '#296DF3',
layout: 'top',

View File

@@ -1,6 +1,5 @@
import RightContent from '@/components/RightContent';
import S2Icon, { ICON } from '@/components/S2Icon';
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
import { Space, Spin, ConfigProvider } from 'antd';
import ScaleLoader from 'react-spinners/ScaleLoader';
import { history, RunTimeLayoutConfig } from '@umijs/max';
@@ -9,6 +8,7 @@ import settings from '../config/themeSettings';
import { queryCurrentUser } from './services/user';
import { deleteUrlQuery, isMobile, getToken } from '@/utils/utils';
import { publicPath } from '../config/defaultSettings';
import type { DefaultSetting } from '../config/defaultSettings';
import { Copilot } from 'supersonic-chat-sdk';
import { configProviderTheme } from '../config/themeSettings';
export { request } from './services/request';
@@ -42,7 +42,7 @@ const getAuthCodes = (params: any) => {
};
export async function getInitialState(): Promise<{
settings?: LayoutSettings;
settings?: DefaultSetting;
currentUser?: API.CurrentUser;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
codeList?: string[];

View File

@@ -7,7 +7,7 @@ import {
getUserAccessTokens,
removeAccessToken,
} from '@/services/user';
import { encryptPassword, encryptKey } from '@/utils/utils';
import { encryptPassword, encryptKey, copyText } from '@/utils/utils';
import { API } from '@/services/API';
import { EditableProTable, ProColumns } from '@ant-design/pro-components';
import { CopyOutlined } from '@ant-design/icons';
@@ -84,8 +84,7 @@ const ChangePasswordModal = forwardRef<IRef>((_, ref) => {
type="link"
size="small"
onClick={() => {
navigator.clipboard.writeText(record.token || '');
message.info('已复制到剪贴板');
copyText(record.token || '');
}}
>
<CopyOutlined />

View File

@@ -1,13 +1,13 @@
import React, { useRef } from 'react';
import { LogoutOutlined, KeyOutlined, UnlockOutlined } from '@ant-design/icons';
import { useModel } from 'umi';
import { useModel } from '@umijs/max';
import HeaderDropdown from '../HeaderDropdown';
import styles from './index.less';
import TMEAvatar from '../TMEAvatar';
import { AUTH_TOKEN_KEY } from '@/common/constants';
import ChangePasswordModal, { IRef as IRefChangePasswordModal } from './ChangePasswordModal';
import AccessTokensModal, { IRef as IAccessTokensModalRef } from './AccessTokensModal';
import { history } from 'umi';
import { history } from '@umijs/max';
export type GlobalHeaderRightProps = {
menu?: boolean;

View File

@@ -1,4 +1,4 @@
import { request } from 'umi';
import { request } from '@umijs/max';
export async function getUserByDeptid(id: any) {
return request<any>(`${process.env.AUTH_API_BASE_URL}user/getUserByOrg/${id}`, {

View File

@@ -1,7 +1,7 @@
import { Button, message, notification } from 'antd';
import React from 'react';
import { useIntl } from 'umi';
import { useIntl } from '@umijs/max';
import defaultSettings from '../config/defaultSettings';
const { pwa } = defaultSettings;
@@ -37,7 +37,7 @@ if (pwa) {
worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
});
// Refresh current page to use the updated HTML and other assets after SW has skiped waiting
window.location.reload(true);
(window.location.reload as (forceReload?: boolean) => void)(true); //兼容老版IE,现在浏览器中此方法均不再接收参数
return true;
};
const key = `open${Date.now()}`;
@@ -75,7 +75,7 @@ if (pwa) {
});
// remove all caches
if (window.caches && window.caches.keys) {
if ('caches' in window) {
caches.keys().then((keys) => {
keys.forEach((key) => {
caches.delete(key);

View File

@@ -1,6 +1,6 @@
import { Button, Result } from 'antd';
import React from 'react';
import { history } from 'umi';
import { history } from '@umijs/max';
const NoAuthPage: React.FC = () => (
<Result

View File

@@ -1,6 +1,6 @@
import { Button, Result } from 'antd';
import React from 'react';
import { history } from 'umi';
import { history } from '@umijs/max';
const NoFoundPage: React.FC = () => (
<Result

View File

@@ -1,4 +1,4 @@
import { request } from 'umi';
import { request } from '@umijs/max';
import { AgentType, MemoryType, MetricType, ModelType } from './type';
export function getAgentList() {

View File

@@ -1,4 +1,4 @@
import { request } from 'umi';
import { request } from '@umijs/max';
import { DimensionType, ModelType, PluginType } from './type';
export function savePlugin(params: Partial<PluginType>) {

View File

@@ -268,7 +268,7 @@ const ModelCreateForm: React.FC<CreateFormProps> = ({
if (!saveState && currentStep < 1) {
forward();
} else {
const { dbName, tableName } = submitForm;
const { catalog ,dbName, tableName } = submitForm;
const queryParams = {
...submitForm,
databaseId: databaseId || modelItem?.databaseId || formDatabaseId,
@@ -278,7 +278,7 @@ const ModelCreateForm: React.FC<CreateFormProps> = ({
modelDetail: {
...submitForm,
queryType: basicInfoFormMode === 'fast' ? 'table_query' : 'sql_query',
tableQuery: dbName && tableName ? `${dbName}.${tableName}` : '',
tableQuery: catalog && dbName && tableName ? `${catalog}.${dbName}.${tableName}` : (dbName && tableName ? `${dbName}.${tableName}` : ''),
sqlQuery: sql,
sqlVariables: sqlParams,
},

View File

@@ -7,7 +7,7 @@ import { XFlowGraphCommands, XFlowNodeCommands, XFlowEdgeCommands } from '@antv/
import { CanvasMiniMap, CanvasScaleToolbar, CanvasSnapline } from '@antv/xflow';
import { MODELS } from '@antv/xflow';
import GraphToolbar from './GraphToolbar/index';
import { connect } from 'umi';
import { connect } from '@umijs/max';
/** 配置画布 */
import { useGraphConfig } from './config-graph';

View File

@@ -1,7 +1,7 @@
import { message, Tabs, Button, Space } from 'antd';
import React, { useState, useEffect } from 'react';
import { getTagData } from '../service';
import { useParams, history } from 'umi';
import { useParams, history } from '@umijs/max';
import styles from './style.less';
import { ArrowLeftOutlined } from '@ant-design/icons';
import TagTrendSection from './components/TagTrendSection';

View File

@@ -2,7 +2,7 @@ import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { ProTable } from '@ant-design/pro-components';
import { message, Space, Popconfirm } from 'antd';
import React, { useRef, useState, useEffect } from 'react';
import { useModel } from 'umi';
import { useModel } from '@umijs/max';
import { SENSITIVE_LEVEL_ENUM } from '../constant';
import { getTagList, deleteTag, batchDeleteTag, getTagObjectList } from '../service';
import TagFilter from './components/TagFilter';

View File

@@ -36,7 +36,7 @@ import TableTitleTooltips from '../../components/TableTitleTooltips';
import { createMetric, updateMetric, mockMetricAlias, getMetricTags } from '../../service';
import { MetricSettingKey, MetricSettingWording } from '../constants';
import { ISemantic } from '../../data';
import { history } from 'umi';
import { history } from '@umijs/max';
export type CreateFormProps = {
datasourceId?: number;

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState, useRef } from 'react';
import { useModel } from 'umi';
import { useModel } from '@umijs/max';
import {
typeConfigs,
formatterRelationData,

View File

@@ -1,6 +1,6 @@
// import { Radio } from 'antd';
import React, { useState } from 'react';
import { connect } from 'umi';
import { connect } from '@umijs/max';
import styles from './components/style.less';
import type { StateType } from './model';
import { SemanticNodeType } from './enum';

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState, useRef } from 'react';
import { Button, message, Form, Space, Drawer, Input } from 'antd';
import { ProCard } from '@ant-design/pro-components';
import { useModel } from 'umi';
import { useModel } from '@umijs/max';
import { createGroupAuth, updateGroupAuth } from '../../service';
import PermissionCreateForm from './PermissionCreateForm';
import type { StateType } from '../../model';

View File

@@ -1,241 +1,243 @@
import type { SqlParamsItem } from '@/pages/data-explore/data';
declare global {
namespace API {
// export type CurrentUser = {
// avatar?: string;
// name?: string;
// title?: string;
// group?: string;
// signature?: string;
// tags?: {
// key: string;
// label: string;
// }[];
// userid?: string;
// access?: 'user' | 'guest' | 'admin';
// unreadCount?: number;
// };
declare namespace API {
// export type CurrentUser = {
// avatar?: string;
// name?: string;
// title?: string;
// group?: string;
// signature?: string;
// tags?: {
// key: string;
// label: string;
// }[];
// userid?: string;
// access?: 'user' | 'guest' | 'admin';
// unreadCount?: number;
// };
export type CurrentUser = {
staffid: string;
staffName: string | undefined;
orgName: string;
access?: 'user' | 'guest' | 'admin';
name?:string;
};
export type CurrentUser = {
staffid: string;
staffName: string;
orgName: string;
access?: 'user' | 'guest' | 'admin';
};
export interface UserItem {
id: number;
name: string;
displayName: string;
email: string;
}
export interface UserItem {
id: number;
name: string;
displayName: string;
email: string;
export interface UserAccessToken {
createDate: string;
expireDate: string;
expireTime: number;
id: number;
name: string;
token: string;
userName: string;
}
export type LoginStateType = {
status?: 'ok' | 'error';
type?: string;
};
export type NoticeIconData = {
id: string;
key: string;
avatar: string;
title: string;
datetime: string;
type: string;
read?: boolean;
description: string;
clickClose?: boolean;
extra: any;
status: string;
};
export type FieldItem = {
fieldname: string; // 字段名
fieldtype: string; // 字段类型
fieldcomment: string; // 释义
dimensionorindex: '0' | '1'; // 维度-0 指标-1
rname: string; // 绑定现有维度/指标 -- name
rguid: string; // 绑定现有维度/指标 -- guid
};
export type QueryChangeLogParams = Pagination & {
typeId: string;
};
export type ChangeLogItem = {
typeId: string;
typeName: string;
changeTime: string; // 变更时间
owner: string; // 操作人
comment: string; // 变更说明
changeDetail: string; // 操作详情
};
export type ChangeLogRes = PaginationResponse<ChangeLogItem>;
export type SearchParams = {
name?: string; // 数据集名称
description?: string; // 数据集描述
bizcodes?: string[]; // 所属项目
dsowner?: string; // 负责人
startEndtime?: sting[]; // 开始-结束时间
assetStatus?: number[]; // 数据集状态
sensitivities?: number[]; // 敏感度
};
export type DataSetListParams = Pagination & SearchParams;
export type DataSetItem = {
guid: string;
longid: number;
name: string; // 数据集名称
description: string; // 数据集描述
datasouce: string; // 数据源名称
datasouceId: number; // 数据源id
tables: string; // 表名
projectId: string; // 业务名称
projectIdStr: string;
owner: string; // 负责人
updateperiod: string; // 更新周期
updateperiodStr: string; // 更新周期
opsource: number; // 来源
createTimeStr: string;
updateTimeStr: string;
assetStatusStr: string; // 上线/下线
isAsset: number; // 是否资产
sensitivity: number;
sensitivityStr: string; // 敏感度
sql: string; // 技术口径
sensitivity: number; // 数据敏感度1-底 2-中 3-高
variables: SqlParamsItem[]; // 数据集归属脚本参数
};
export type DataSetListRes = PaginationResponse<DataSetItem>;
export type DataSetBasicInfo = DataSetItem;
export type DimensionListSearchParams = {
name: string; // 中文名
dimensionSource: string[]; // 来源
projectIds: string[]; // 所属项目
dimensionbizName: string; // 英文名
description: string; // 描述
};
export type QueryFieldListParams = Pagination & {
guid: string;
name?: string;
};
export type DataSetFieldItem = {
columnXh: number; // 顺序标记从0开始
name: string; // 字段名
fieldtype: string; // 字段类型
description: string; // 释义
dimensionorindex: '0' | '1'; // 维度-0 指标-1
assetStatusStr: string; // 状态
rname: string; // 绑定现有维度/指标 -- name
rguid: string; // 绑定现有维度/指标 -- guid
};
export type DataSetFieldListRes = PaginationResponse<DataSetFieldItem>;
// 搜索条件
export type DataTableSearchParams = {
name: string; // 表名
description: string; // 描述详情
extDatasouceenums: string[]; // 数据库类型
extDwlayerenums: string[]; // 数仓分层
extBizenums: string[]; // 所属项目
queryRanges: string[]; // 查看范围
storagesize: string; // 存储大小
owner: string; // 所有者
createtime: string; // 创建时间
};
export type DataTableListParams = Pagination & DataTableSearchParams;
// 数据表列表
export type DataTableListItem = {
guid: string;
name: string; // 表名
description: string; // 描述
projectFullName: string; // 所属项目
isSpeedStr: string; // 是否加速
dbName: string; // 库名
dwLayer: string; // 数据分层
assetSensitivityStr: string; // 数据敏感度
storageSize: string; // 储存大小
owner: string; // 所有者
createTime: string; // 创建时间
dbTableName: string; // 库名::表名
};
// 数据表列表
export type DataTableListRes = PaginationResponse<DataTableListItem>;
// 业务项目对象
export type ProjectItem = AuthSdkType.AuthCodesItem & {
projectId: string; // 项目ID
projectIncreId: number; // 项目自增ID
projectName: string; // 项目名
projectParentId: string; // 父项目ID
projectFullName: string; // 父项目-子项目
projectLevel: number; // 项目层级
comment: string; // 项目描述
creator: string; // 项目创建人
projectType: number; // 项目类别 0-为私有项目 1-为公共项目
childDomainList?: DomainList;
children?: DomainList;
value: string;
};
export type DomainList = ProjectItem[];
// 数据实例详情
export type DataInstanceDetail = {
type: string; // 类型 mysql、tdw
id: string; // id
name: string; // 名称
description: string; // 描述
ip?: string; // ip
port?: string; // 端口
bootstrap?: string; // 连接地址
};
export type AuthCodeItem = {
code: string; // 权限码
approverLevel: number;
ext: string;
isMenu: number;
isVisible: number;
no: number;
pcode: string;
url: string;
};
// 数据库查询参数
export type DatabaseParams = {
bindSourceId: number;
};
// 数据库列表子项
export type DatabaseItem = {
dbName: string; // 数据库名
cnt: number; // 库中有权限表数量
};
// 数据类型
export type DataInstanceItem = {
sourceInstanceId: number; // 数据实例id
sourceInstanceName: string; // 数据实例名
defaultSourceId: number; // 查询表需要的默认datasource id
bindSourceId: number;
};
}
export interface UserAccessToken {
createDate: string;
expireDate: string;
expireTime: number;
id: number;
name: string;
token: string;
userName: string;
}
export type LoginStateType = {
status?: 'ok' | 'error';
type?: string;
};
export type NoticeIconData = {
id: string;
key: string;
avatar: string;
title: string;
datetime: string;
type: string;
read?: boolean;
description: string;
clickClose?: boolean;
extra: any;
status: string;
};
export type FieldItem = {
fieldname: string; // 字段名
fieldtype: string; // 字段类型
fieldcomment: string; // 释义
dimensionorindex: '0' | '1'; // 维度-0 指标-1
rname: string; // 绑定现有维度/指标 -- name
rguid: string; // 绑定现有维度/指标 -- guid
};
export type QueryChangeLogParams = Pagination & {
typeId: string;
};
export type ChangeLogItem = {
typeId: string;
typeName: string;
changeTime: string; // 变更时间
owner: string; // 操作人
comment: string; // 变更说明
changeDetail: string; // 操作详情
};
export type ChangeLogRes = PaginationResponse<ChangeLogItem>;
export type SearchParams = {
name?: string; // 数据集名称
description?: string; // 数据集描述
bizcodes?: string[]; // 所属项目
dsowner?: string; // 负责人
startEndtime?: sting[]; // 开始-结束时间
assetStatus?: number[]; // 数据集状态
sensitivities?: number[]; // 敏感度
};
export type DataSetListParams = Pagination & SearchParams;
export type DataSetItem = {
guid: string;
longid: number;
name: string; // 数据集名称
description: string; // 数据集描述
datasouce: string; // 数据源名称
datasouceId: number; // 数据源id
tables: string; // 表名
projectId: string; // 业务名称
projectIdStr: string;
owner: string; // 负责人
updateperiod: string; // 更新周期
updateperiodStr: string; // 更新周期
opsource: number; // 来源
createTimeStr: string;
updateTimeStr: string;
assetStatusStr: string; // 上线/下线
isAsset: number; // 是否资产
sensitivity: number;
sensitivityStr: string; // 敏感度
sql: string; // 技术口径
sensitivity: number; // 数据敏感度1-底 2-中 3-高
variables: SqlParamsItem[]; // 数据集归属脚本参数
};
export type DataSetListRes = PaginationResponse<DataSetItem>;
export type DataSetBasicInfo = DataSetItem;
export type DimensionListSearchParams = {
name: string; // 中文名
dimensionSource: string[]; // 来源
projectIds: string[]; // 所属项目
dimensionbizName: string; // 英文名
description: string; // 描述
};
export type QueryFieldListParams = Pagination & {
guid: string;
name?: string;
};
export type DataSetFieldItem = {
columnXh: number; // 顺序标记从0开始
name: string; // 字段名
fieldtype: string; // 字段类型
description: string; // 释义
dimensionorindex: '0' | '1'; // 维度-0 指标-1
assetStatusStr: string; // 状态
rname: string; // 绑定现有维度/指标 -- name
rguid: string; // 绑定现有维度/指标 -- guid
};
export type DataSetFieldListRes = PaginationResponse<DataSetFieldItem>;
// 搜索条件
export type DataTableSearchParams = {
name: string; // 表名
description: string; // 描述详情
extDatasouceenums: string[]; // 数据库类型
extDwlayerenums: string[]; // 数仓分层
extBizenums: string[]; // 所属项目
queryRanges: string[]; // 查看范围
storagesize: string; // 存储大小
owner: string; // 所有者
createtime: string; // 创建时间
};
export type DataTableListParams = Pagination & DataTableSearchParams;
// 数据表列表
export type DataTableListItem = {
guid: string;
name: string; // 表名
description: string; // 描述
projectFullName: string; // 所属项目
isSpeedStr: string; // 是否加速
dbName: string; // 库名
dwLayer: string; // 数据分层
assetSensitivityStr: string; // 数据敏感度
storageSize: string; // 储存大小
owner: string; // 所有者
createTime: string; // 创建时间
dbTableName: string; // 库名::表名
};
// 数据表列表
export type DataTableListRes = PaginationResponse<DataTableListItem>;
// 业务项目对象
export type ProjectItem = AuthSdkType.AuthCodesItem & {
projectId: string; // 项目ID
projectIncreId: number; // 项目自增ID
projectName: string; // 项目名
projectParentId: string; // 父项目ID
projectFullName: string; // 父项目-子项目
projectLevel: number; // 项目层级
comment: string; // 项目描述
creator: string; // 项目创建人
projectType: number; // 项目类别 0-为私有项目 1-为公共项目
childDomainList?: DomainList;
children?: DomainList;
value: string;
};
export type DomainList = ProjectItem[];
// 数据实例详情
export type DataInstanceDetail = {
type: string; // 类型 mysql、tdw
id: string; // id
name: string; // 名称
description: string; // 描述
ip?: string; // ip
port?: string; // 端口
bootstrap?: string; // 连接地址
};
export type AuthCodeItem = {
code: string; // 权限码
approverLevel: number;
ext: string;
isMenu: number;
isVisible: number;
no: number;
pcode: string;
url: string;
};
// 数据库查询参数
export type DatabaseParams = {
bindSourceId: number;
};
// 数据库列表子项
export type DatabaseItem = {
dbName: string; // 数据库名
cnt: number; // 库中有权限表数量
};
// 数据类型
export type DataInstanceItem = {
sourceInstanceId: number; // 数据实例id
sourceInstanceName: string; // 数据实例名
defaultSourceId: number; // 查询表需要的默认datasource id
bindSourceId: number;
};
}

View File

@@ -17,7 +17,9 @@ export const TOKEN_KEY = AUTH_TOKEN_KEY;
const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
const headers: any = {};
const query = queryString.parse(history.location.search) || {};
const token = query[TOKEN_KEY] || localStorage.getItem(TOKEN_KEY);
const rawToken = query[TOKEN_KEY];
const token = (typeof rawToken === 'string' ? rawToken : null) || localStorage.getItem(TOKEN_KEY);
if (token) {
headers.Authorization = `Bearer ${token}`;
headers.auth = `Bearer ${token}`;